from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status, serializers
from rest_framework_simplejwt.tokens import RefreshToken
from rest_framework.permissions import IsAuthenticated, AllowAny
from django.contrib.auth.hashers import check_password
from django.contrib.auth import authenticate, get_user_model
from django.conf import settings
from .serializers import ForgotPasswordSerializer, UserSerializer, UpdatePasswordSerializer
from django.contrib.auth.tokens import default_token_generator
from django.utils.http import urlsafe_base64_encode, urlsafe_base64_decode
from django.utils.encoding import force_bytes, force_str
import smtplib, requests
from email.mime.text import MIMEText
from email.header import Header
from django.views.decorators.csrf import csrf_exempt
from django.http import JsonResponse
import json
User = get_user_model()
@csrf_exempt
def get_wenxin_token(request):
    if request.method == 'POST':
        try:
            # 解析 JSON 数据
            data = json.loads(request.body)
            api_key = data.get("apiKey")
            secret_key = data.get("secretKey")
            print(f"Received API Key: {api_key}, API Secret: {secret_key}")

            if not api_key or not secret_key:
                return JsonResponse({"error": "API key or secret key missing"}, status=400)

            # 向百度 API 请求获取 token
            url = "https://aip.baidubce.com/oauth/2.0/token"
            response = requests.post(
                url,
                params={
                    "grant_type": "client_credentials",
                    "client_id": api_key,
                    "client_secret": secret_key
                },
            )
            response.raise_for_status()

            # 获取 access_token
            data = response.json()
            access_token = data.get("access_token")
            if access_token:
                return JsonResponse({
                    'message': 'Token retrieved successfully.',
                    'code': '200',
                    'data': {
                        'access_token': access_token,
                    }
                }, status=200)
            else:
                return JsonResponse({"error": "Failed to retrieve access token from Baidu"}, status=500)

        except requests.exceptions.RequestException as e:
            return JsonResponse({"error": f"Request failed: {str(e)}"}, status=500)
        except json.JSONDecodeError:
            return JsonResponse({"error": "Invalid JSON data"}, status=400)
        except Exception as e:
            return JsonResponse({"error": f"Unexpected error: {str(e)}"}, status=500)
    return JsonResponse({"error": "Invalid method, only POST allowed"}, status=405)

import json
import requests
from django.views.decorators.csrf import csrf_exempt
from django.http import JsonResponse
from django.conf import settings


from django.http import JsonResponse
import json

class ChatView(APIView):
    permission_classes = [IsAuthenticated]

    def post(self, request):
        try:
            # 解析请求体中的数据
            data = json.loads(request.body)
            models = data.get("models")  # 获取模型列表，应该是 ['ernie']
            message = data.get("message")  # 获取消息内容
            access_token = data.get("access_token", None)  # 可选的 token，用于 Wenxin

            # 初始化返回结果
            response_data = []

            # 如果未选择任何模型或没有提供消息内容
            if not models or not message:
                return Response({
                    "code": 400,
                    "message": "Model and message are required"
                }, status=status.HTTP_400_BAD_REQUEST)

            # 针对每个选中的模型进行调用
            for model in models:
                if model == "ernie":
                    response = call_wenxin(message, access_token)
                elif model == "openai":
                    response = call_openai(message, access_token)
                elif model == "deepseek":
                    response = call_deepseek(message, access_token)
                else:
                    response_data.append({"model": model, "error": "Invalid model selected"})
                    continue

                # 将模型的响应结果添加到返回结果列表
                response_data.append({"model": model, "response": response})

            # 构造返回的最终数据结构
            result = {
                "data": response_data,
                "code": 200,
                "message": "success"
            }

            # 返回数据
            return Response(result, status=status.HTTP_200_OK)

        except Exception as e:
            return Response({
                "code": 500,
                "message": str(e)
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)




import requests

def call_deepseek(message, api_key):
    """与 DeepSeek API 进行对话"""
    url = "https://api.deepseek.com/v1/chat/completions"
    
    headers = {
        'Authorization': f'Bearer {api_key}',
        'Content-Type': 'application/json'
    }
    
    # DeepSeek 可能期望的消息格式
    messages = [
        {"role": "user", "content": message}  # 假设消息格式为 [{"role": "user", "content": "your message"}]
    ]
    
    data = {
        "model": "deepseek-chat",  # 使用 DeepSeek 特定的模型名称
        "messages": messages,      # 传递消息数组
        "stream": False            # 设置为 False 以获取非流式响应
    }
    
    try:
        # 发送 POST 请求到 DeepSeek API
        response = requests.post(url, json=data, headers=headers)
        response.raise_for_status()  # 如果请求失败，会抛出异常
        
        # 返回助手的回复
        return response.json().get('choices', [{}])[0].get('message', {}).get('content', 'No content')
    
    except requests.exceptions.RequestException as e:
        # 如果请求失败，返回错误信息
        raise Exception(f"DeepSeek API error: {e}")



def call_openai(message, access_token):
    """与 OpenAI 进行对话"""
    try:
        response = requests.post('https://api.baicaigpt.cn/v1/chat/completions', 
                                 headers={'Authorization': f'Bearer {access_token}'},
                                 json={"model": "gpt-3.5-turbo", "messages": [{"role": "user", "content": message}]})
        response.raise_for_status()
        return response.json().get('choices', [{}])[0].get('message', {}).get('content', 'No result')
    except requests.exceptions.RequestException as e:
        raise Exception(f"OpenAI API error: {e}")


def call_wenxin(message, access_token):
    """与文心（Wenxin）进行对话"""
    try:
        # 文心 API URL
        url = f"https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/completions_pro?access_token={access_token}"

        # 请求数据
        payload = {
            "messages": [{"role": "user", "content": message}],  # 将消息格式调整为符合要求
            "temperature": 0.8,
            "top_p": 0.8,
            "penalty_score": 1,
            "enable_citation": False,
            "disable_search": False,
            "collapsed": True,
        }

        # 发送请求到文心接口
        response = requests.post(
            url,
            headers={'Content-Type': 'application/json'},
            data=json.dumps(payload)  # 确保请求体格式正确
        )

        # 打印请求数据和响应内容以供调试
        print('请求数据:', payload)
        print('响应数据:', response.text)  # 打印响应内容

        # 确认响应是否成功
        response.raise_for_status()

        # 获取响应中的内容
        response_data = response.json()
        print('响应 JSON 数据:', response_data)  # 打印完整的 JSON 响应

        # 从响应中提取结果
        choices = response_data.get('result')  # 根据实际返回结构提取信息
        if choices:
            return choices
        else:
            return 'No result'

    except requests.exceptions.RequestException as e:
        raise Exception(f"Wenxin API error: {e}")




def generate_reset_link(user,email):
    """生成密码重置链接"""
    uid = urlsafe_base64_encode(force_bytes(user.pk))
    token = default_token_generator.make_token(user)
    return uid, token, f"http://localhost:3000/reset-password?email={email}&uid={uid}&token{token}/"


def send_reset_email(email, reset_link):
    """发送密码重置邮件"""
    # SMTP服务器配置
    smtp_server = 'smtp.qq.com'  # QQ邮箱SMTP服务器地址
    smtp_port = 587  # SMTP服务器端口（TLS加密）
    smtp_user = '823457467@qq.com'  # 发件人邮箱账号
    smtp_password = 'trhovbcufycvbfgi'  # 发件人邮箱授权码

    # 邮件内容
    subject = "Password Reset"
    body = f"Click the link to reset your password: {reset_link}"
    
    # 创建MIMEText对象
    msg = MIMEText(body, 'plain', 'utf-8')
    
    # 设置 From 头信息
    sender_name = "hello ceshi"  # 发件人名称
    sender_email = smtp_user  # 发件人邮箱地址
    msg['From'] = f"{Header(sender_name, 'utf-8')} <{sender_email}>"

    # 设置 To 和 Subject 头信息
    msg['To'] = email  # 收件人邮箱
    msg['Subject'] = Header(subject, 'utf-8')

    try:
        print(f"Attempting to connect to SMTP server at {smtp_server}:{smtp_port}")
        server = smtplib.SMTP(smtp_server, smtp_port)
        server.starttls()
        print(f"Starting TLS encryption")
        server.login(smtp_user, smtp_password)
        print(f"Logged in to SMTP server with user {smtp_user}")
        server.sendmail(smtp_user, [email], msg.as_string())
        print(f"Email sent successfully to {email}")
        server.quit()
        return True
    except smtplib.SMTPAuthenticationError as e:
        print(f"SMTP Authentication Error: {e}")
        return False
    except Exception as e:
        print(f"Error sending email: {e}")
        return False

class ForgotPasswordAPIView(APIView):
    permission_classes = [AllowAny]

    def post(self, request):
        serializer = ForgotPasswordSerializer(data=request.data)
        if serializer.is_valid():
            email = serializer.validated_data['email']

            try:
                user = User.objects.get(email=email)
                uid, token, reset_link = generate_reset_link(user,email)
                print('uid, token',uid, token)
                if not send_reset_email(email, reset_link):
                    return Response({"error": "Failed to send email. Please try again."}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
                return Response({"message": "Password reset email sent successfully!", "uid": uid, "token": token}, status=status.HTTP_200_OK)
            except User.DoesNotExist:
                return Response({"error": "No user found with this email."}, status=status.HTTP_400_BAD_REQUEST)

class HelloView(APIView):
    def get(self, request):
        return Response({'message': 'Hello, World!'}, status=status.HTTP_200_OK)

class ProtectedView(APIView):
    permission_classes = [IsAuthenticated]

    def get(self, request):
        return Response({'message': 'This is a protected view.'}, status=status.HTTP_200_OK)

# 登录
class LoginView(APIView):
    permission_classes = [AllowAny]

    def post(self, request):
        username = request.data.get('username')
        password = request.data.get('password')

        # 验证用户名和密码
        user = authenticate(username=username, password=password)

        if user is not None:
            # 登录成功，生成 JWT 令牌
            refresh = RefreshToken.for_user(user)
            return Response({
                'message': 'Login successful.',
                'code': '200',
                'data': {
                    'refreshToken': str(refresh),
                    'token': str(refresh.access_token),
                }
            }, status=status.HTTP_200_OK)
        else:
            # 认证失败，返回 401 错误
            return Response({
                'code': '500',
                'msg': '用户名或密码错误！.',
                'data': {'non_field_errors': ['Invalid username or password.']}
            }, status=status.HTTP_401_UNAUTHORIZED)

# 获取用户信息
class GetUserInfoView(APIView):
    permission_classes = [IsAuthenticated]

    def get(self, request):
        if request.user.is_authenticated:
            user = request.user
            print(user)
            
            # 构造返回的用户数据
            user_data = {
                "userId": str(user.id),  # 这里假设 user.id 是用户的 ID
                "userName": user.username,  # 假设用户的用户名是 user.username
                "roles": ["ROLE_SUPER"]  # 可以根据实际情况进行动态处理
            }
            
            # 构造返回的最终数据结构
            response_data = {
                "data": user_data,
                "code": 200,
                "message": "success"
            }
            
            # 返回数据
            return Response(response_data, status=status.HTTP_200_OK)
        else:
            # 认证失败，返回 401 错误
            return Response({
                "code": 401,
                "message": "认证失败."
            }, status=status.HTTP_401_UNAUTHORIZED)


        

# 注册
class RegisterView(APIView):
    permission_classes = [AllowAny]

    def post(self, request):
        serializer = UserSerializer(data=request.data)
        
        try:
            if serializer.is_valid(raise_exception=True):
                user = serializer.save()
                return Response({'message': 'User registered successfully.'}, status=status.HTTP_201_CREATED)
        except serializers.ValidationError as e:
            # 如果用户名或电子邮件已存在，返回 400 错误
            return Response({
                'message': 'Registration failed.',
                'errors': e.detail
            }, status=status.HTTP_400_BAD_REQUEST)

        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

# 更新密码
class UpdatePasswordView(APIView):
    permission_classes = [IsAuthenticated]
    
    def post(self, request, *args, **kwargs):
        serializer = UpdatePasswordSerializer(data=request.data)
        if not serializer.is_valid():
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

        current_password = serializer.validated_data['current_password']
        new_password = serializer.validated_data['new_password']

        user = request.user

        # 验证当前密码是否正确
        if not check_password(current_password, user.password):
            return Response({
                'message': 'Current password is incorrect!',
            }, status=status.HTTP_400_BAD_REQUEST)

        # 更新用户密码
        user.set_password(new_password)
        user.save()

        return Response({'message': 'Password updated successfully'}, status=status.HTTP_200_OK)

# 验证密码重置令牌并更新密码
class ResetPasswordConfirmView(APIView):
    def get(self, request, uidb64, token):
        try:
            uid = force_str(urlsafe_base64_decode(uidb64))
            user = User.objects.get(pk=uid)
        except (TypeError, ValueError, OverflowError, User.DoesNotExist) as e:
            print(f"Error decoding UID or fetching user: {e}")
            user = None

        if user is not None and default_token_generator.check_token(user, token):
            # Token is valid, you can render a form to reset the password
            return Response({"message": "Valid token", "uid": uid, "token": token}, status=status.HTTP_200_OK)
        else:
            # Invalid token
            return Response({"error": "Invalid token"}, status=status.HTTP_400_BAD_REQUEST)

    def post(self, request, uidb64, token):
        try:
            uid = force_str(urlsafe_base64_decode(uidb64))
            user = User.objects.get(pk=uid)
        except (TypeError, ValueError, OverflowError, User.DoesNotExist) as e:
            print(f"Error decoding UID or fetching user: {e}")
            user = None

        if user is not None and default_token_generator.check_token(user, token):
            new_password = request.data.get('new_password')
            confirm_password = request.data.get('confirm_password')

            if new_password != confirm_password:
                return Response({"error": "Passwords do not match"}, status=status.HTTP_400_BAD_REQUEST)

            user.set_password(new_password)
            user.save()
            return Response({"message": "Password reset successfully!"}, status=status.HTTP_200_OK)
        else:
            return Response({"error": "Invalid token"}, status=status.HTTP_400_BAD_REQUEST)